home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / EventQueue.java < prev    next >
Text File  |  1998-10-25  |  9KB  |  300 lines

  1. /*
  2.  * @(#)EventQueue.java    1.21 98/07/21
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.awt;
  16.  
  17. import java.awt.event.FocusEvent;
  18. import java.awt.event.KeyEvent;
  19. import java.awt.event.MouseEvent;
  20. import java.awt.event.PaintEvent;
  21. import java.awt.event.WindowEvent;
  22. import java.util.EventListener;
  23.  
  24. import java.util.Vector;
  25.  
  26. /**
  27.  * EventQueue is a platform-independent class that queues events, both
  28.  * from the underlying peer classes and from trusted application classes.
  29.  * There is only one EventQueue for the system.
  30.  *
  31.  * @version 1.21 07/21/98
  32.  * @author Thomas Ball
  33.  */
  34. public class EventQueue {
  35.  
  36.     // From Thread.java
  37.     private static int threadInitNumber;
  38.     private static synchronized int nextThreadNum() {
  39.     return threadInitNumber++;
  40.     }
  41.  
  42.     private EventQueueItem queue;
  43.     /* The multiplexed EventQueueListener list. */
  44.     EventQueueListener eventQueueListener;
  45.  
  46.     public EventQueue() {
  47.         queue = null;
  48.         String name = "AWT-EventQueue-" + nextThreadNum();
  49.         new EventDispatchThread(name, this).start();
  50.     }
  51.  
  52.     /**
  53.      * Post a 1.1-style event to the EventQueue.
  54.      *
  55.      * @param theEvent an instance of java.awt.AWTEvent, or a
  56.      * subclass of it.
  57.      */
  58.     public synchronized void postEvent(AWTEvent theEvent) {
  59.         EventQueueItem eqi = new EventQueueItem(theEvent);
  60.     if (queue == null) {
  61.         queue = eqi;
  62.         notifyAll();
  63.     } else {
  64.         EventQueueItem q = queue;
  65.         for (;;) {
  66.         if (q.id == eqi.id) {
  67.             switch (q.id) {
  68.               case Event.MOUSE_MOVE:
  69.               case Event.MOUSE_DRAG:
  70.               // New-style event id's never collide with 
  71.               // old-style id's, so if the id's are equal, 
  72.               // we can safely cast the queued event to be 
  73.               // an old-style one.
  74.               MouseEvent e = (MouseEvent)q.event;
  75.               if (e.getSource() == ((MouseEvent)theEvent).getSource() &&
  76.                   e.getModifiers() == ((MouseEvent)theEvent).getModifiers()) {
  77.                   q.event = eqi.event;// just replace old event
  78.                   return;
  79.               }
  80.               break;
  81.  
  82.               case PaintEvent.PAINT:
  83.               case PaintEvent.UPDATE:
  84.               PaintEvent pe = (PaintEvent)q.event;
  85.               if (pe.getSource() == theEvent.getSource()) {
  86.                   Rectangle rect = pe.getUpdateRect();
  87.                   Rectangle newRect = 
  88.                   ((PaintEvent)theEvent).getUpdateRect();
  89.                   if (!rect.equals(newRect)) {
  90.                   pe.setUpdateRect(rect.union(newRect));
  91.                   }
  92.                   return;
  93.               }
  94.               break;
  95.  
  96.             }
  97.         }
  98.         if (q.next != null) {
  99.             q = q.next;
  100.         } else {
  101.             break;
  102.         }
  103.         }
  104.         q.next = eqi;
  105.     }
  106.     notifyEventQueueListeners(theEvent);
  107.     }
  108.  
  109.     /**
  110.      * Remove an event from the queue and return it.  This method will
  111.      * block until an event has been posted by another thread.
  112.      * @return the next AWTEvent
  113.      * @exception InterruptedException 
  114.      *            if another thread has interrupted this thread.
  115.      */
  116.     public synchronized AWTEvent getNextEvent() throws InterruptedException {
  117.         while (queue == null) {
  118.             wait();
  119.         }
  120.         EventQueueItem eqi = queue;
  121.         queue = queue.next;
  122.         return eqi.event;
  123.     }
  124.  
  125.     /**
  126.      * Return the first event without removing it.
  127.      * @return the first event, which is either an instance of java.awt.Event
  128.      * or java.awt.AWTEvent.
  129.      */
  130.     public synchronized AWTEvent peekEvent() {
  131.         return (queue != null) ? queue.event : null;
  132.     }
  133.  
  134.     /*
  135.      * Return the first event of the specified type, if any.
  136.      * @param id the id of the type of event desired.
  137.      * @return the first event of the requested type, 
  138.      * which is either an instance of java.awt.Event
  139.      * or java.awt.AWTEvent.
  140.      */
  141.     public synchronized AWTEvent peekEvent(int id) {
  142.         EventQueueItem q = queue;
  143.         for (; q != null; q = q.next) {
  144.             if (q.id == id) {
  145.                 return q.event;
  146.             }
  147.         }
  148.         return null;
  149.     }
  150.  
  151.     /* comment out until 1.2...
  152.     /**
  153.      * Dispatch an event to its source.
  154.      *
  155.      * @param theEvent an instance of java.awt.AWTEvent, or a
  156.      * subclass of it.
  157.      *
  158.      *    protected void dispatchEvent(AWTEvent event) {
  159.      *        Object src = event.getSource();
  160.      *        if (src instanceof Component) {
  161.      *            ((Component)src).dispatchEvent(event);
  162.      *        } else if (src instanceof MenuComponent) {
  163.      *            ((MenuComponent)src).dispatchEvent(event);
  164.      *        }
  165.      *    }
  166.      */
  167.  
  168.     /*
  169.      * (Copied from new public 1.2 API)
  170.      * Adds listener to event queue
  171.      */
  172.     synchronized void addEventQueueListener(EventQueueListener l) {
  173.         eventQueueListener = EventQueueMulticaster.add(eventQueueListener, l);
  174.     }
  175.  
  176.     /*
  177.      * (Copied from new public 1.2 API)
  178.      * Removes listener from event queue
  179.      */
  180.     synchronized void removeEventQueueListener(EventQueueListener l) {
  181.         eventQueueListener = EventQueueMulticaster.remove(eventQueueListener, l);
  182.     }
  183.  
  184.  
  185.     /*
  186.      * Change the target of any pending KeyEvents because of a focus change.
  187.      */
  188.     synchronized void changeKeyEventFocus(Object newSource) {
  189.         EventQueueItem q = queue;
  190.         for (; q != null; q = q.next) {
  191.             if (q.event instanceof KeyEvent) {
  192.                 q.event.setSource(newSource);
  193.             }
  194.         }
  195.     }
  196.  
  197.     /*
  198.      * Remove any pending events for the specified source object.
  199.      * This method is normally called by the source's removeNotify method.
  200.      */
  201.     synchronized void removeSourceEvents(Object source) {
  202.         EventQueueItem entry = queue;
  203.         EventQueueItem prev = null;
  204.         while (entry != null) {
  205.             if (entry.event.getSource().equals(source)) {
  206.                 if (prev == null) {
  207.                     queue = entry.next;
  208.                 } else {
  209.                     prev.next = entry.next;
  210.                 }
  211.             }
  212.             prev = entry;
  213.             entry = entry.next;
  214.         }
  215.     }
  216.  
  217.     /*
  218.      * Remove any pending events of the given class and id
  219.      */
  220.     synchronized void removeEvents(Class evClass, int id) {
  221.         EventQueueItem entry = queue;
  222.         EventQueueItem prev = null;
  223.         while (entry != null) {
  224.             if (evClass.isInstance(entry.event) && entry.event.getID() == id) {
  225.                 if (prev == null) {
  226.                     queue = entry.next;
  227.                 } else {
  228.                     prev.next = entry.next;
  229.                 }
  230.             }
  231.             prev = entry;
  232.             entry = entry.next;
  233.         }
  234.     }
  235.  
  236.     static private class EventQueueMulticaster extends AWTEventMulticaster
  237.         implements EventQueueListener {
  238.         // Implementation cloned from AWTEventMulticaster.
  239.  
  240.         EventQueueMulticaster(EventListener a, EventListener b) {
  241.             super(a, b);
  242.         }
  243.  
  244.         static EventQueueListener add(EventQueueListener a,
  245.                                       EventQueueListener b) {
  246.             return (EventQueueListener)addInternal(a, b);
  247.         }
  248.  
  249.         static EventQueueListener remove(EventQueueListener l,
  250.                                          EventQueueListener oldl) {
  251.             return (EventQueueListener) removeInternal(l, oldl);
  252.         }
  253.         
  254.         // __SYMC__ JavaSoft bug #4178589
  255.         protected EventListener remove(EventListener oldl) {
  256.             if (oldl == a)  return b;
  257.             if (oldl == b)  return a;
  258.             EventListener a2 = removeInternal(a, oldl);
  259.             EventListener b2 = removeInternal(b, oldl);
  260.             if (a2 == a && b2 == b) {
  261.                 return this;    // it's not here
  262.             }
  263.             return addInternal(a2, b2);
  264.         }
  265.         // __SYMC__
  266.  
  267.     protected static EventListener addInternal(EventListener a, EventListener b)
  268.     {
  269.         if (a == null)  return b;
  270.         if (b == null)  return a;
  271.         return new EventQueueMulticaster(a, b);
  272.     }
  273.  
  274.         public void eventPosted(AWTEvent e) {
  275.             ((EventQueueListener)a).eventPosted(e);
  276.             ((EventQueueListener)b).eventPosted(e);
  277.         }
  278.     }
  279.  
  280.     /*
  281.      * Based on new protected 1.2 API
  282.      */
  283.     private void notifyEventQueueListeners(AWTEvent theEvent) {
  284.         if (eventQueueListener != null) {
  285.             eventQueueListener.eventPosted(theEvent);
  286.         }
  287.     }
  288. }
  289.  
  290. class EventQueueItem {
  291.     AWTEvent event;
  292.     int      id;
  293.     EventQueueItem next;
  294.  
  295.     EventQueueItem(AWTEvent evt) {
  296.         event = evt;
  297.         id = evt.getID();
  298.     }
  299. }
  300.